/**
 * 
 */
package neptune.web.server.repository;

import it.robertobifulco.ias.OperationRepository;
import it.robertobifulco.ias.RepositoryException;
import it.robertobifulco.ias.principalmanager.ImpossibleToIdentifyPrincipalException;
import it.robertobifulco.ias.principalmanager.PrincipalRepository;
import it.robertobifulco.ias.rolemanager.RoleRepository;
import it.robertobifulco.ias.rolemanager.RoleUndefinedException;

import java.util.ArrayList;
import java.util.Iterator;

import neptune.manager.ExperimentException;
import neptune.manager.model.experiment.Experiment;
import neptune.manager.storage.ExperimentRepositoryException;
import neptune.web.server.model.ApplicationUser;
import neptune.web.server.operations.AddUser;
import neptune.web.server.operations.AddUserToExperiment;
import neptune.web.server.operations.DeleteExperiment;
import neptune.web.server.operations.ExperimentCreation;
import neptune.web.server.operations.GetExperiment;
import neptune.web.server.operations.GetUser;
import neptune.web.server.operations.GetUsers;
import neptune.web.server.operations.RemoveUser;
import neptune.web.server.operations.RemoveUserFromExperiment;
import neptune.web.server.operations.RequestExperimentStart;
import neptune.web.server.operations.StartExperiment;
import neptune.web.server.operations.StopExperiment;
import neptune.web.server.operations.TerminateExperiment;
import neptune.web.server.operations.TopologyConfiguration;
import neptune.web.server.operations.UpdateUser;
import neptune.web.server.operations.UsersInfo;
import neptune.web.server.operations.WriteTopologyFile;

/**
 * @author Roberto Bifulco [info@robertobifulco.it, robertobifulco.it]
 * 
 */
public class ApplicationRepositoryTEST implements PrincipalRepository,
		RoleRepository, OperationRepository, ApplicationRepository {

	private static ApplicationRepositoryTEST instance = new ApplicationRepositoryTEST();
	private ArrayList<ApplicationUser> users = new ArrayList<ApplicationUser>(0);

	private ApplicationRepositoryTEST() {
		ApplicationUser roberto = new ApplicationUser(false, "System Admin",
				"Roberto");
		roberto.setEmail("rob.bifulco@studenti.unina.it");
		roberto.setPassword("123");

		users.add(roberto);
	}

	public static ApplicationRepositoryTEST instance() {
		return instance;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @seeit.robertobifulco.ias.principalmanager.PrincipalRepository#
	 * getPrincipalPassword(java.lang.String)
	 */
	public String getPrincipalPassword(String principalID)
			throws ImpossibleToIdentifyPrincipalException {
		for (Iterator<ApplicationUser> iterator = users.iterator(); iterator
				.hasNext();) {
			ApplicationUser appUsr = (ApplicationUser) iterator.next();

			if (appUsr.getId().equals(principalID))
				return appUsr.getPassword();
		}
		throw new ImpossibleToIdentifyPrincipalException(
				"No principal with such name");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * it.robertobifulco.ias.principalmanager.PrincipalRepository#getPrincipalRole
	 * (java.lang.String)
	 */
	public String getPrincipalRole(String principalID)
			throws ImpossibleToIdentifyPrincipalException {
		for (Iterator<ApplicationUser> iterator = users.iterator(); iterator
				.hasNext();) {
			ApplicationUser appUsr = (ApplicationUser) iterator.next();

			if (appUsr.getId().equals(principalID))
				return appUsr.getRole();
		}
		throw new ImpossibleToIdentifyPrincipalException(
				"No principal with such name");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * neptune.manager.ExperimentsRepository#addExperimentToRepository(neptune
	 * .manager.model.experiment.Experiment)
	 */
	public void addExperimentToRepository(Experiment experiment)
			throws ExperimentException {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * neptune.manager.ExperimentsRepository#addToAllocationQueue(neptune.manager
	 * .model.experiment.Experiment)
	 */
	public void addToAllocationQueue(Experiment experiment) {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see neptune.manager.ExperimentsRepository#getActiveExperiments()
	 */
	public Experiment[] getActiveExperiments() {
		// TODO Auto-generated method stub
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * neptune.manager.ExperimentsRepository#getExperimentByName(java.lang.String
	 * )
	 */
	public Experiment getExperimentByName(String name) {
		// TODO Auto-generated method stub
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see neptune.manager.ExperimentsRepository#getExperiments()
	 */
	public Experiment[] getExperiments() {
		// TODO Auto-generated method stub
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * neptune.manager.ExperimentsRepository#removeExperimentFromRepository(
	 * neptune.manager.model.experiment.Experiment)
	 */
	public void removeExperimentFromRepository(Experiment experiment) {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * neptune.manager.ExperimentsRepository#removeFromAllocationQueue(neptune
	 * .manager.model.experiment.Experiment, boolean)
	 */
	public void removeFromAllocationQueue(Experiment experiment,
			boolean allocated) {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * neptune.web.server.repository.ApplicationRepository#addUser(neptune.web
	 * .server.model.ApplicationUser)
	 */
	public void addUser(ApplicationUser user) throws RepositoryException {
		users.add(user);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * neptune.web.server.repository.ApplicationRepository#removeUser(neptune
	 * .web.server.model.ApplicationUser)
	 */
	public void removeUser(ApplicationUser user) throws RepositoryException {
		users.remove((ApplicationUser) user);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * neptune.web.server.repository.ApplicationRepository#updateUser(neptune
	 * .web.server.model.ApplicationUser)
	 */
	public void updateUser(ApplicationUser user) throws RepositoryException {
		users.remove(user);
		users.add(user);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * neptune.web.server.repository.ApplicationRepository#getUserByName(java
	 * .lang.String)
	 */
	public ApplicationUser getUserByName(String username)
			throws RepositoryException {
		for (Iterator<ApplicationUser> iterator = users.iterator(); iterator
				.hasNext();) {
			ApplicationUser appUsr = (ApplicationUser) iterator.next();

			if (appUsr.getId().equals(username))
				return appUsr;
		}
		throw new RepositoryException("No user with such name");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see neptune.web.server.repository.ApplicationRepository#getUsers(int,
	 * int, int, boolean)
	 */
	public ApplicationUser[] getUsers(int begin, int end, int sortId,
			boolean sortAscending) {

		return (ApplicationUser[]) users.toArray(new ApplicationUser[0]);
	}

	public void updateExperiment(Experiment experiment)
			throws ExperimentRepositoryException {
		// TODO Auto-generated method stub

	}

	public String[] getRoleOperations(String roleName)
			throws RoleUndefinedException {
		if (roleName.equals("System Admin"))
			return new String[] { TopologyConfiguration.ID, AddUser.ID,
					GetUsers.ID, RemoveUser.ID, GetUser.ID, UsersInfo.ID,
					UpdateUser.ID, ExperimentCreation.ID, DeleteExperiment.ID,
					GetExperiment.ID, AddUserToExperiment.ID,
					RemoveUserFromExperiment.ID, WriteTopologyFile.ID,
					StartExperiment.ID, RequestExperimentStart.ID,
					StopExperiment.ID, TerminateExperiment.ID };

		return new String[] { UsersInfo.ID, ExperimentCreation.ID,
				DeleteExperiment.ID, GetExperiment.ID, AddUserToExperiment.ID,
				RemoveUserFromExperiment.ID, WriteTopologyFile.ID,
				RequestExperimentStart.ID, StopExperiment.ID,
				TerminateExperiment.ID };
	}

	public String[] getRoles() {
		String[] roles = new String[] { "System Admin", "User" };
		return roles;
	}

	public void updateOperationsList(String[] operationIdentifiers,
			String[] operationDescriptions) {
		// TODO Auto-generated method stub

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * neptune.web.server.repository.ApplicationRepository#removeUserByName(
	 * java.lang.String)
	 */
	public boolean removeUserByName(String username) 
	{
		return users.remove(new ApplicationUser(false,	ApplicationUser.UNDEFINED_VALUE, username));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see neptune.web.server.repository.ApplicationRepository#getUsersNumber()
	 */
	public int getUsersNumber() {
		return users.size();
	}
}
